#!/usr/bin/perl -w	# useful for syntax highlighting
package clreqd_modules;

use cldb;
use Data::Dumper;
use pidlock;
use C_client2;
use Sys::Hostname;

#########################################################################
# This utility is used to indicate whether the particular daemon is	#
# running on the host. Requres a DAEMON argument which can be a		#
# comma-separated list to get multiple results.				#
#									#
# Output is:								#
# Name	YES/NO								#
#									#
# For example:								#
# OK									#
# lha_lockd	YES							#
# lha_statd	NO							#
#									#
# or:									#
# FAIL error message.							#
#									#
#########################################################################

sub daemon_stat {
my %ARGS=@_;
my @D=qw(hbd lockd netd lockd syncd statd mond clusterd);
my $attempts=1;

	my $d=$ARGS{DAEMON};
	my @qu=split(/,/,$d);
	$attempts=int($ARGS{ATTEMPTS}) if exists($ARGS{ATTEMPTS});
	if($attempts<1) {
		$attempts=1;
	}

	for (@qu) {
		s/^lha_//;
		$_.="d" if ! /d$/;
	}
	for $d (@qu) {
		if(!scalar(grep {/^$d$/} @D)) {
			return "FAIL Daemon '$d' is unknown.";
		}
	}
	my $cldb=undef;

	my @r=();
	my %responses=();
	$responses{$_}="NO" for (@qu);
	my $c_attempt=1;
	while($c_attempt<=$attempts) {
		::msg("Attempt $c_attempt");
		for $d (@qu) {
			if(exists($responses{$d}) && $responses{$d} eq "YES") {
				::msg("Ignoring '$d' - already had response.");
				next;
			}
			my $pl=new pidlock($d);
			if(!defined($pl)) {
				return "FAIL Unable to create pidlock object:\n" . pidlock::error;
			}
			my $r=$pl->islocked;
			if($r==-1) {
				return "FAIL Unable to check for lock object:\n" . pidlock::error;
			}
			if($r==0) {
				#################################################
				# No lock, then check PING request, just 	#
				# in case no lock file was created.		#
				#################################################
				if(!defined($cldb)) {
					$cldb=new cldb("$::ENV{TRUECL_CFG}/config.db");
					if(!defined($cldb)) {
						::error("Unable to open database:\n" . cldb::error);
					}
				}
				if(defined($cldb)) {
					my ($client,$port);
					my $h=$cldb->get_rows("SELECT number FROM ports WHERE detail = 'lha_$d';");
					if(!defined($h) || !defined($h->[0])) {
						::error("Port not found for 'lha_$d' in config database.");
					} else {
						$port=$h->[0]->{number};
						$client=new C_client2(SERVER_NAME => hostname,SERVER_INET => "127.0.0.1",
								SERVER_PORT=>$port, PKI=>$::PKI);
						if(!defined($client)) {
							::error("Unable to gain connection to 'lha_$d'.");
						} else {
							$client->set_params(TIMEOUT => 1);

						#########################################################################
						# We have a connection, so send a message via it and wait for the	#
						# response.								#
						#########################################################################

							my ($resp,$err)=$client->send_request("PING");
							if(defined($resp) && $resp =~ /OK/) {
								$r=1;
							}
							if($r==0) {
								::msg("Response for $d: $resp") if defined($resp);
							}
						}
					}
				}
				$responses{$d}="YES" if $r==1;
				$responses{$d}="NO" if $r==0;
			}
		}
		$c_attempt++;
		#########################################################
		# If all responses are YES then break out of loop	#
		#########################################################
		my $all_yes=1;
		for my $x (keys(%responses)) {
			if($responses{$x} ne "YES") {
				$all_yes=0;
				last;
			}
		}
		if($all_yes==0) {
			select(undef,undef,undef,0.25);
			next;
		}
		last if $all_yes==1;
	}
	for my $x(keys(%responses)) {
		push @r,"$x $responses{$x}";
	}
	$cldb->disconnect() if defined($cldb);
	::msg("Response for daemon_stat: " . join(" ",@r));
	return "OK\n".join("\n",@r);
}

1;
